/**
 * Copyright © 2013 Creativor Studio.
 * About license information, please see LICENSE.txt.
 */
package org.creativor.rayson.serialize;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.lang.reflect.Array;

/**
 * @author creativor
 * 
 */
final class StringType extends SerializableType<String> {

	/**
	 * @param type
	 */
	protected StringType(final byte type) {
		super(type);
	}

	@Override
	String read(final DataInput dis) throws SerializeFormatException, IOException,
			UnsupportedTypeException {
		final short length = dis.readShort();
		final byte[] bytes = new byte[length];
		dis.readFully(bytes);
		return new String(bytes);
	}

	@Override
	Object readArray(final DataInput dis, final int arrayLength) throws SerializeFormatException,
			IOException {
		final Object array = Array.newInstance(String.class, arrayLength);
		String item;
		boolean nullItem;
		for (int i = 0; i < arrayLength; i++) {
			try {
				item = null;
				nullItem = dis.readBoolean();
				if (!nullItem)
					try {
						item = read(dis);
					} catch (final UnsupportedTypeException e) {
						throw new SerializeFormatException("Can not read array item", e);
					}
				Array.set(array, i, item);
			} catch (ArrayIndexOutOfBoundsException | IllegalArgumentException e) {
				// Ignore it.
			}
		}
		return array;
	}

	@Override
	void write(final DataOutput dos, final String value) throws IOException,
			UnsupportedTypeException {
		final byte[] bytes = value.getBytes();
		dos.writeShort(bytes.length);
		dos.write(bytes);
	}

	@Override
	void writeArray(final DataOutput dos, final Object array) throws IOException,
			UnsupportedTypeException {

		final int arrayLength = Array.getLength(array);
		String item;
		boolean nullItem;
		for (int i = 0; i < arrayLength; i++) {
			try {
				item = (String) Array.get(array, i);
				nullItem = (item == null);
				dos.writeBoolean(nullItem);
				if (!nullItem)
					this.write(dos, item);
			} catch (ArrayIndexOutOfBoundsException | IllegalArgumentException e) {
				// Ignore it.
			}
		}
	}
}